<?php

namespace app\admin\controller;

use think\Db;
use think\Request;
use think\Validate;

class User extends BaseController
{
    // 设置模型名称
    protected $modelName = 'user';

    protected $uniqueFields = ['account'];

    protected $fieldLabels = [
        'account' => '账号',
    ];

    // 设置验证规则
    // 添加自定义string验证规则
    public function __construct()
    {
        parent::__construct();
        Validate::extend('string', function ($value) {
            return is_string($value);
        },               '必须是字符串类型');
    }

    // 设置验证规则
    protected $validateRules = [
        'id' => 'number',
        'account' => 'require|max:20',
        'password' => 'require|max:20'
    ];

    // 设置规则提示
    protected $validateRulesMsg = [
        'account.require' => '账号不能为空',
        'password.require' => '密码不能为空',
        'account.max' => '账号最多20个字符',
        'password.max' => '密码最多20个字符',
    ];


    /**
     * 新增/编辑前的钩子方法
     * 重写父类方法以处理用户数据
     * @param array $data 要处理的数据
     * @return array 处理后的数据
     */
    protected function beforeAddOrEdit($data)
    {
        // 设置username为account的值
        if (isset($data['account'])) {
            $data['username'] = $data['account'];
        }

        // 生成随机盐
        $data['salt'] = $this->generateSalt();

        return $data;
    }

    /**
     * 生成随机盐
     * @return string 随机盐
     */
    protected function generateSalt()
    {
        $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        $salt = '';
        for ($i = 0; $i < 6; $i++) {
            $salt .= $chars[mt_rand(0, strlen($chars) - 1)];
        }
        return $salt;
    }

    /**
     * 用户登录
     */
    public function login()
    {
        $input = Request()->param();

        $account = $input['account'];
        $password = $input['password'];

        if (empty($account)) apiReturn(2, '账号不能为空');
        if (empty($password)) apiReturn(2, '密码不能为空');

        $user = $this->model->where('account', $account)->find();
        if (!$user) apiReturn(2, '账号不存在');

        // 检查用户是否被禁用
        if (isset($user['status']) && $user['status'] != 1) {
            apiReturn(2, '账号已被禁用');
        }

        $salt = $user['salt'];
        $password = thinkEncrypt($password . $salt);

        if ($user['password'] != $password) apiReturn(2, '密码错误');

        $ip = request()->ip();

        // 更新用户登录信息
        $updateData = [
            'last_login_time' => date('Y-m-d H:i:s'),
            'last_login_ip' => $ip,
            'login_count' => $user['login_count'] + 1
        ];
        $this->model->where('id', $user['id'])->update($updateData);

        // 记录登录日志
        $this->recordLoginLog($user['id'], $ip);

        // 获取用户权限数据
        if($auth_group_ids = $user['auth_group_ids']) {
            $rules = Db::name('auth_group')->whereIn('id', $auth_group_ids)->column('rules');
            $rules_str = implode(',', $rules);
            $auth_data = array_values(array_unique(explode(',', $rules_str)));
        }

        // 生成登录会话信息
        $login_info = [
            'account' => $user['account'],
            'username' => $user['username']
        ];
        $token = md5($account . $password . time() . uniqid());
        session($token, $login_info);

        $data = [
            'token' => $token,
            'user' => $login_info,
            'auth_data' => $auth_data ? : []
        ];

        apiReturn(1, '登录成功', $data);
    }

    /**
     * 记录登录日志
     * @param int    $userId 用户ID
     * @param string $ip     登录IP
     */
    protected function recordLoginLog($userId, $ip)
    {
        try {
            Db::name('login_log')->insert([
                                              'user_id' => $userId,
                                              'ip' => $ip,
                                              'login_time' => time()
                                          ]);
        } catch (\Exception $e) {
            // 日志记录失败不影响登录流程
            \think\Log::record('记录登录日志失败: ' . $e->getMessage());
        }
    }

    /**
     * 管理员列表
     * */
    public function getList()
    {
        $list = $this->model->order('id desc')->select();
        if ($list) {
            foreach ($list as &$v) {
                $auth_group_desc = '';
                if ($auth_group_ids = $v['auth_group_ids']) {
                    $auth_group_list = Db::name('auth_group')->whereIn('id', $auth_group_ids)->column('name');
                    $auth_group_list = array_filter((array)$auth_group_list);
                    $auth_group_desc = implode(',', $auth_group_list);
                }
                $v['auth_group_desc'] = $auth_group_desc;
            }
        }
        apiReturn(1, '获取成功', $list);
    }

    /**
     * 分配角色
     * */
    public function assignRoles()
    {
        $input = Request()->param();

        $id = $input['id'];
        $auth_group_ids = $input['auth_group_ids'] ? : '';

        if (empty($id)) apiReturn(2, '管理员ID不能为空');

        $res = $this->model->where('id', $id)->update(['auth_group_ids' => $auth_group_ids, 'update_time' => time()]);
        if ($res) {
            apiReturn(1, '分配角色成功');
        } else {
            apiReturn(2, '分配角色失败');
        }
    }

    /**
     * 初始化用户密码
     */
    public function initPassword()
    {
        $id = $this->request->param('id', 0);

        if (empty($id)) apiReturn(2, '用户ID不能为空');

        // 检查用户是否存在
        $user = $this->model->find($id);
        if (!$user) apiReturn(2, '用户不存在');

        $salt = $user['salt'];

        // 初始化密码为123456并加密
        $password = thinkEncrypt('123456' . $salt);

        // 更新用户信息
        $user->password = $password;
        $res = $this->model->where('id', $id)->update(['password' => $password, 'update_time' => time()]);

        if ($res) {
            apiReturn(1, '密码已成功初始化为123456');
        } else {
            apiReturn(2, '密码初始化失败');
        }
    }
}
